﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace SpaceFight
{


class Camera
{
	public Matrix View { get; private set; }
	public Matrix Projection { get; private set; }
	public float AspectRatio;
	public Vector3 Position
	{
		get { return m_position; }
		set { m_position = value; Update(); }
	}
	
	Vector3 m_lookDir = Properties.Settings.Default.CameraLookDir;
	Vector3 m_upDir;
	Vector3 m_rightDir;
	Vector3 m_position = Properties.Settings.Default.CameraPosition;

	static Camera ms_instance = null;

	public static void createInstance(Vector3 p_position, Vector3 p_lookat, Vector3 p_up)
	{
		System.Diagnostics.Debug.Assert(ms_instance == null);
		ms_instance = new Camera(p_position, p_lookat, p_up);
	}
	public static void destroyInstance()
	{
		System.Diagnostics.Debug.Assert(ms_instance != null);
		ms_instance = null;
	}
	public static Camera getInstance()
	{
		System.Diagnostics.Debug.Assert(ms_instance != null);
		return ms_instance;
	}
	private Camera(Vector3 p_position, Vector3 p_lookat, Vector3 p_up)
	{
		AspectRatio = 0;
		m_upDir = p_up;
		m_position = p_position;
		m_lookDir = p_lookat - m_position;
		m_lookDir = Properties.Settings.Default.CameraLookDir;
		m_position = Properties.Settings.Default.CameraPosition;
		Update();
	}

	public void Update()
	{
		if(Keyboard.GetState().IsKeyDown(Keys.L))
		{
			m_lookDir = Properties.Settings.Default.CameraLookDir;
			m_position = Properties.Settings.Default.CameraPosition;
		}
		
		if (m_lookDir. LengthSquared() != 0) m_lookDir. Normalize();
		m_rightDir = Vector3.Cross(m_lookDir, Vector3.Up);
		m_upDir    = Vector3.Cross(m_rightDir, m_lookDir);
		
		View = Matrix.CreateLookAt(m_position, m_position + m_lookDir, m_upDir);
		Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
		                                                 AspectRatio, 1.0f, 100000000.0f);

		//DebugInfoViewer.DebugMain.ShowDebugInfo("position", m_position.ToString(), this);
		//DebugInfoViewer.DebugMain.ShowDebugInfo("lookDir", m_lookDir.ToString(), this);
		
		if(Keyboard.GetState().IsKeyDown(Keys.O))
		{
			Properties.Settings.Default.CameraLookDir = m_lookDir;
			Properties.Settings.Default.CameraPosition = m_position;
		}

	}

	public void rotateAroundUp(double p_radials)
	{
		Quaternion quad = Quaternion.CreateFromAxisAngle(m_upDir, (float)p_radials);
		m_lookDir  = Vector3.Transform(m_lookDir , quad);
		m_rightDir = Vector3.Transform(m_rightDir, quad);
	}
	public void rotateAroundRight(double p_radials)
	{
		Quaternion quad = Quaternion.CreateFromAxisAngle(m_rightDir, (float)p_radials);
		m_lookDir = Vector3.Transform(m_lookDir, quad);
		m_upDir   = Vector3.Transform(m_upDir  , quad);
	}

	public void moveForward(double p_value)
	{
		m_position += m_lookDir * (float)p_value;
	}
	public void moveRight(double p_value)
	{
		m_position += m_rightDir * (float)p_value;
	}
}


}
